#include "HighScoresState.h"
#include "MainMenuState.h"
//#include "GameplayState.h"
#include "../GameplayStates/GameOverState.h"
#include "../DeadlyShadowsLastHope/Game.h"
#include "../SGD Wrappers/SGD_String.h"
#include "CreditState.h"
using std::ostringstream;
#include <sstream>

CHighScoresState* CHighScoresState::GetInstance(void)
{
	static CHighScoresState s_Instance;
	return &s_Instance;
}

CHighScoresState::CHighScoresState(void)
{
	m_pD3D = nullptr;
	m_pTM = nullptr;
	m_pDI = nullptr;
	m_pXA = nullptr;
	m_sVol = 0;
	m_nScreenWidth = CGame::GetInstance()->GetWidth();
	m_nScreenHeight = CGame::GetInstance()->GetHeight();
	m_nBackGroundImageID = -1;
	//m_nHighScore			= -1;
}

CHighScoresState::~CHighScoresState(void) { }

void CHighScoresState::Enter(void)
{
	//setup the state
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
	m_pXA	= CSGD_XAudio2::GetInstance();

	m_pFont.Load("../resources/XML/DeadlyShadowsFont.xml");

	m_nBackGroundImageID = m_pTM->LoadTexture(	_T("../resources/graphics/high_score_menu.png")/*, D3DCOLOR_XRGB(0, 0, 0)*/ );

	if( LoadPlayers( vPlayers, "players.xml" ) == false )
		GeneratePlayers( vPlayers  );

	SavePlayers(vPlayers , "players.xml" );

}

void CHighScoresState::Exit(void)
{
	if (this->m_nBackGroundImageID != -1)
	{
		this->m_pTM->UnloadTexture(this->m_nBackGroundImageID);
		this->m_nBackGroundImageID = -1;
	}
}

bool CHighScoresState::Input(void)
{
	if (m_pDI->KeyPressed(DIK_ESCAPE))
	{
		CGame::GetInstance()->AddState(CMainMenuState::GetInstance());
		CGame::GetInstance()->RemoveState(this);
	}
	if (m_pDI->KeyPressed(DIK_RETURN))
	{
		CGame::GetInstance()->AddState(CCreditState::GetInstance());
		CGame::GetInstance()->RemoveState(this);
	}
	return true;
}

void CHighScoresState::Render(void)
{
	m_pTM->Draw(m_nBackGroundImageID, 0, 0, 0.8f, 0.6f, nullptr, 0, 0, 0); 
	m_pD3D->GetSprite()->Flush();

	//this->m_pFont->Print("high scores", (int)(m_nScreenWidth * 0.15f), (int)(m_nScreenHeight * 0.17f), 1.5f, D3DXCOLOR(255,0,255,255));
	this->m_pFont.Print("Initials", (int)(m_nScreenWidth * 0.20f), (int)(m_nScreenHeight * 0.25f), 1.0f, D3DXCOLOR(0,255,255,255));
	this->m_pFont.Print("Scores", (int)(m_nScreenWidth * 0.50f), (int)(m_nScreenHeight * 0.25f), 1.0f, D3DXCOLOR(0,255,255,255));
	
	DisplayPlayers( vPlayers );
}

void CHighScoresState::Update(float fElapsedTime)
{

}

void CHighScoresState::GeneratePlayers(vector <tPlayerInfo>& vPlayers)
{
	//Generate defualt players
	tPlayerInfo p1 = { "AAA", 000 };
	tPlayerInfo p2 = { "AAA", 000 };
	tPlayerInfo p3 = { "AAA", 000 };
	tPlayerInfo p4 = { "AAA", 000 };
	tPlayerInfo p5 = { "AAA", 000 };
	tPlayerInfo p6 = { "AAA", 000 };
	tPlayerInfo p7 = { "AAA", 000 };
	tPlayerInfo p8 = { "AAA", 000 };
	tPlayerInfo p9 = { "AAA", 000 };
	tPlayerInfo p10 = { "AAA", 000 };

	vPlayers.clear();

	vPlayers.push_back(p1);
	vPlayers.push_back(p2);
	vPlayers.push_back(p3);
	vPlayers.push_back(p4);
	vPlayers.push_back(p5);
	vPlayers.push_back(p6);
	vPlayers.push_back(p7);
	vPlayers.push_back(p8);
	vPlayers.push_back(p9);
	vPlayers.push_back(p10);
}

void CHighScoresState::DisplayPlayers (const vector <tPlayerInfo>& vPlayers)
{	
	ostringstream oss;
	int move = 0;

	vector <tPlayerInfo>::const_iterator iter;
	for ( iter = vPlayers.begin(); iter!= vPlayers.end(); ++iter)
	{
		m_pFont.Print((*iter).m_cName, (int)(m_nScreenWidth * 0.20f), (int)(m_nScreenHeight * 0.3f)+ move, 1.0f, D3DXCOLOR(255,0,255,255));
		oss << (*iter).m_nHighScore;
		//above need to use the timer for highscore time.

		m_pFont.Print(oss.str().c_str(), (int)(m_nScreenWidth * 0.50f), (int)(m_nScreenHeight * 0.3f)+ move, 1.0f, D3DXCOLOR(255,0,255,255));
		oss.str("");
		move += 30;
	}
}

bool CHighScoresState::LoadPlayers(vector<tPlayerInfo>& vPlayers, const char* szFilename)
{
	// Create a TinyXML Document
	TiXmlDocument doc;

	// Attempt to load the file
	//doc.
	if( doc.LoadFile( szFilename ) == false )
		return false;

	// Access the root node ("players_list")
	TiXmlElement* pRoot = doc.RootElement();

	if( pRoot == nullptr )
		return false;

	// Clear the existing players (if any)
	vPlayers.clear();

	// Iterate through the nodes to load player info
	TiXmlElement* pPlayer = pRoot->FirstChildElement( "player_info" );

	while( pPlayer != nullptr )
	{
		// Info structure
		tPlayerInfo info = { };

		//Read the name
		const char* pText = pPlayer->GetText();
		if (pText != nullptr)
			strcpy_s(info.m_cName, 4, pText);
		else
			strcpy_s(info.m_cName, 4, "EMPTY");

		//Read the attributes
		pPlayer->Attribute("score", &info.m_nHighScore);

		//Save the info into the vetor
		vPlayers.push_back(info);

		//Move to the next "player_info"
		pPlayer = pPlayer->NextSiblingElement("player_info");
	}
	return true;
}

void CHighScoresState::SavePlayers (const vector<tPlayerInfo>& vPlayers, const char* szFilename)
{
	TiXmlDocument doc;
	TiXmlDeclaration* pDec = new TiXmlDeclaration ("1.0", "utf-8", "");
	doc.LinkEndChild(pDec);
	TiXmlElement* pRoot = new TiXmlElement("players_list");
	doc.LinkEndChild(pRoot);

	vector< tPlayerInfo >::const_iterator iter;
	for( iter = vPlayers.begin(); iter != vPlayers.end(); ++iter )
	{
		// Create a node for this player
		TiXmlElement* pPlayer = new TiXmlElement( "player_info" );


		// Fill the node with player's data
		pPlayer->SetAttribute( "score", (*iter).m_nHighScore );


		// Create a Text node for the player's name
		TiXmlText* pText = new TiXmlText( (*iter).m_cName );
		pPlayer->LinkEndChild( pText );


		// Write the player node to the root "players_list"
		pRoot->LinkEndChild( pPlayer );
	}

	// Save the document to the file
	doc.SaveFile( szFilename );

}